#ifndef MODULE_WINDOW_H
#define MODULE_WINDOW_H

#include <QFrame>
#include <QMouseEvent>
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QGraphicsTextItem>
#include <QGraphicsSceneEvent>

#include "module/property/module_port_property.h"
#include "module/property/module_window_property.h"
#include "module/property/module_propertys.h"

//#include "module/modulefileconfig.h"
#include "module/module_header.h"


namespace Ui {
class module_window;
}

#define MODULE_DEFAULT_xRadius 25
#define MODULE_DEFAULT_yRadius 25
#define MODULE_DEFAULT_MARGIN 60
#define DEFAULT_CHILD_MODULE_SIZE QSize(300, 200)

///---------------------------------------------------------------

class Module_Graph : public QObject, public QGraphicsItem
{
    Q_OBJECT
    Q_INTERFACES(QGraphicsItem)
public:
    Module_Graph(QSizeF size, Module_Data *data,QGraphicsItem *parent = nullptr);
    Module_Graph(QGraphicsItem *parent = nullptr);
    ~Module_Graph();

    void make_module_property(Module_Data *data);

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    QRectF boundingRect() const;

    void setName(QString name, QColor color);

public slots:
    void change_label(QString);

signals:
//    void send_modulePressSignal(QGraphicsItem *, ModuleWindowType type);
//    void send_moduleDoubleClickSignal(Module_Graph *);

protected:
    qreal module_width, module_height;
    QGraphicsTextItem *Name = nullptr;

    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);

private:
    Module_Data *Data;

};

class ChildModule : public Module_Graph
{
    Q_OBJECT
public:
    ChildModule(QSizeF size, Child_Module_Data *data, Module_Graph *parent);
    ~ChildModule();

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

    void make_module_property();

public slots:
    void change_label(QString);

protected:
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);

    QVariant itemChange(GraphicsItemChange change, const QVariant &value);

    QPainterPath shape() const;

private:
    Module_Graph *module_parent;
    Child_Module_Data *Data;
};

///---------------------------------------------------------------

class ModulePort : public Module_Graph
{
    Q_OBJECT
public:
    ModulePort(PortAttribute *data, QGraphicsItem *parent);
    ~ModulePort();

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

    void make_port_property(PortAttribute *data);

    qreal compute_port_y(int num, int sum);

signals:
//    void send_portPressSignal(QGraphicsItem *, ModuleWindowType type);

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
    void setRect();

private:
    QGraphicsItem *module;
    PortAttribute *Data;
};

///---------------------------------------------------------------

class ModuleLine : public QGraphicsLineItem
{
public:
    ModuleLine(QGraphicsItem *startItem, QGraphicsItem *endItem);
    ~ModuleLine();

    virtual QRectF boundingRect() const;
    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

private:
    QGraphicsItem *_startItem, *_endItem;
};


///---------------------------------------------------------------


class ModuleScene : public QGraphicsScene
{
    Q_OBJECT
public:
    explicit ModuleScene(QObject *parent = nullptr);

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *);
};


///---------------------------------------------------------------

class module_window : public QFrame
{
    Q_OBJECT

public:

    explicit module_window(Module_Data *data, QWidget *parent = nullptr);

    void set_module_name(QString name);

    void add_child_module(Module_Data *data, QString name, QPointF point, bool add_child = false);

    void add_connect_line(ModuleLine *line);

    void init();

    static void make_code_window(Module_Data *);

    ///---------------------------------------------------------------

    QString get_module_name();
    QString get_module_type();
    QString get_module_class();
    QString code_generate();
    ~module_window();

signals:
    void changeLableName(QString name);

public slots:
    void setLableName(QString name);

protected:
//    void mousePressEvent(QMouseEvent *event) override;

private:
    Ui::module_window *ui;

    Module_Data *module_data;

    QRect window_rect;

//    QGraphicsScene *scene = new QGraphicsSce;ne(this);
    ModuleScene *scene = new ModuleScene(this);

    // public init()
    void init_module();
    void init_port(Module_Graph *module, Module_Data *data); // 创建端口
    void init_child_module();

    Module_Graph *master_module;

    QMap<QGraphicsItem *, Module_Data *> module_map;
    QMap<QGraphicsItem *, PortAttribute> module_port_map;
};

///---------------------------------------------------------------


#endif // MODULE_WINDOW_H
